package main

import (
	"fmt"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promauto"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"log"
	"net/http"
	"prometheus-examples/mymath"
	"time"
)

var urls = []string{"/hello", "/login", "/index", "/list"}

func main() {
	// 设置访问路由
	http.HandleFunc("/hello", hello)

	// 添加prometheus client
	http.Handle("/metrics", promhttp.Handler())
	gauge()
	counter()
	histogram()
	summary()
	err := http.ListenAndServe(":8080", nil) //设置监听端口
	if err != nil {
		log.Fatal("ListenAndServe error:", err)
	}
}

func hello(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello") //输出到客户端
}

// see : https://prometheus.io/docs/guides/go-application/
// see : https://godoc.org/github.com/prometheus/client_golang/prometheus
// 测试gauge
func gauge() {
	memUsage := promauto.NewGauge(prometheus.GaugeOpts{
		Name: "mem_usage",
		Help: "current memory usage",
	})
	go func() {
		for ; ; {
			usage := mymath.RandomInt(20, 30)	//模拟内存使用大小
			memUsage.Set(float64(usage))
			time.Sleep(5 * time.Second) //休眠5s
		}
	}()
}

// 测试counter
func counter() {
	counterVec := promauto.NewCounterVec(prometheus.CounterOpts{
		Name: "web_request_total",
		Help: "web request total",
	}, []string{"url"})
	go func() {
		for ; ; {
			//counterVec.WithLabelValues(url).Inc()	//模拟接口请求
			requestCount := mymath.RandomInt(1, 10)
			counterVec.WithLabelValues(getUrl()).Add(float64(requestCount))	//模拟接口请求
			time.Sleep(5 * time.Second)
		}
	}()
}

// 测试histogram
func histogram()  {
	histogramVec := promauto.NewHistogramVec(prometheus.HistogramOpts{
		Name: "api_cost",
		Help: "api cost with ms",
		Buckets: []float64{10, 50, 100, 500, 1000, 5000},
	}, []string{"url"})

	go func() {
		for ; ; {
			cost := mymath.RandomInt(9, 5010)
			histogramVec.WithLabelValues(getUrl()).Observe(float64(cost))	//模拟接口耗时
			time.Sleep(1 * time.Second)
		}
	}()
}

// 测试summary
func summary() {
	summary := promauto.NewSummary(prometheus.SummaryOpts{
		Name: "api_duration",
		Help: "api duration",
		Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
	})

	go func() {
		for ; ; {
			cost := mymath.RandomInt(1, 2000)
			summary.Observe(float64(cost))
			time.Sleep(5 * time.Second)
		}
	}()
}

func getUrl() string {
	index := mymath.RandomInt(0, 4)
	return urls[index]
}